import createMatcher from "./create-matcher";
import HashHistory from "./history/hash";
import BrowserHistory from "./history/history";
import install from "./install";

class VueRouter {
  constructor(options) {
    const routes = options.routes;

    // 将路由变成映射表，可以匹配路由，也可以添加新的路由
    this.matcher = createMatcher(routes);
    // 存储beforeEach 中的回调函数
    this.beforeEachHooks = [];

    // 根据不同的路由模式创建对应的路由系统，默认hash
    const mode = options.mode || "hash";

    if (mode === "hash") {
      this.history = new HashHistory(this);
    } else if (mode === "history") {
      this.history = new BrowserHistory(this);
    }
  }

  // 匹配路由，找到对应路由的组件信息
  match(location) {
    return this.matcher.match(location)
  }

  // 跳转路由
  push(location) {
    this.history.push(location);
  }

  // 初始化路由
  init(app) {
    const history = this.history;
    // 根据路径的变化匹配对的组件来进行渲染，路径变化了需要重新更新视图（响应式）
    // 根据路径匹配到对应的路由，然后监听路由的变化
    history.transitionTo(history.getCurrentLocation(), () => {
      // 监听路由变化
      history.setupListener();
    })

    // 为的就是更新根实例上_route 的值，使它能够监听数据的变化而重新渲染视图
    history.listen((newRoute) => {
      // newRoute => 路径变化后传入的当前路由信息
      app._route = newRoute;
    })
  }

  // 路由前置守卫
  beforeEach(cb) {
    this.beforeEachHooks.push(cb);
  }
}

// 注册的时候，如果是一个类，会默认调用install 方法
VueRouter.install = install;

export default VueRouter
